using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using MediaPortal.GUI.Library;
//using MediaPortal.Utils.Services;
using System.ComponentModel;
using System.Web;
using System.Net;
using System.Xml;
using System.Xml.XPath;
using System.Threading;
using OnlineVideos.Database;
using System.Text.RegularExpressions;

using MediaPortal.Configuration;

namespace OnlineVideos
{
	public abstract class SiteUtilBase
	{
		public class RssItem
		{
			public String title;
			public String link;
			public String guid;
			public String pubDate;
			public String description;
			public String author;
			public String mediaTitle;
			public String mediaDescription;
			public String mediaThumbnail;
			public String mediaCategory;
			public String exInfoImage;
			public List<MediaContent> contentList;
            public String gameID;
			public String enclosure;
			public String enclosureDuration;
			public String feedBurnerOrigLink;
			public RssItem(){
				contentList = new List<MediaContent>();
			}
		}
		public class MediaContent
		{
			public String url;
			public String type;
			public String medium;
			public String duration;
			public String width;
			public String height;
			
			
		}
		//protected ILog moLog;
		private static bool _workerCompleted = true;
		private string HTMLdownload;
		//protected static SiteUtilBase _Instance;
		ArrayList m_VideoExtensions = new ArrayList();
		
		
		public SiteUtilBase()
		{
			using (MediaPortal.Profile.Settings xmlreader = new MediaPortal.Profile.Settings(Config.GetFile(Config.Dir.Config, "MediaPortal.xml")))
			{
				String strTmp = xmlreader.GetValueAsString("movies", "extensions", ".avi,.mpg,.ogm,.mpeg,.mkv,.wmv,.ifo,.qt,.rm,.mov,.sbe,.dvr-ms,.ts");
				String [] tok = strTmp.Split( ',');
				foreach (string extension in tok)
				{
					m_VideoExtensions.Add(extension.ToLower());
				}
			}
			m_VideoExtensions.Add(".flv");
		}
		
		public virtual List<GUIOnlineVideos.VideoInfo> getSiteFavorites(String fsUser){
			return new List<GUIOnlineVideos.VideoInfo>();
		}
		public abstract List<GUIOnlineVideos.VideoInfo> getVideoList(String fsUrl);
		public virtual List<GUIOnlineVideos.VideoInfo> getRelatedVideos(String fsTags){
			return new List<GUIOnlineVideos.VideoInfo>();
		}
		public virtual List<GUIOnlineVideos.RssLink> getDynamicCategories(String lsUrl)
		{
			return new List<GUIOnlineVideos.RssLink>();

		}
        public virtual List<GUIOnlineVideos.RssLink> getDynamicCategories()
        {
            return null;
        }
		protected virtual String getUrl(String fsId)
		{
			return "";
		}
		
		public virtual bool hasNextPage()
		{
			return false;
		}
		public virtual List<GUIOnlineVideos.VideoInfo> getNextPageVideos()
		{
			return new List<GUIOnlineVideos.VideoInfo>();
		}
		public virtual bool hasPreviousPage()
		{
			return false;
		}
		public virtual List<GUIOnlineVideos.VideoInfo> getPreviousPageVideos()
		{
			return new List<GUIOnlineVideos.VideoInfo>();
		}

		//public virtual bool addFavorite(String fsId,String fsUserName,String fsPassword){
		public virtual void AddFavorite(GUIOnlineVideos.VideoInfo foVideo,String fsSiteId){
			//return false;
			Log.Info("SiteUtilBase AddFavorites.");
			
			FavoritesDatabase db = FavoritesDatabase.getInstance();
			db.addFavoriteVideo(foVideo,fsSiteId);
			
		}
		public virtual bool RemoveFavorite(GUIOnlineVideos.VideoInfo foVideo){
			Log.Info("SiteUtilBase removeFavorites.");
			FavoritesDatabase db = FavoritesDatabase.getInstance();
			return db.removeFavoriteVideo(foVideo);
		}
		
		public virtual String getUrl(GUIOnlineVideos.VideoInfo video,GUIOnlineVideos.SiteSettings foSite)
		{
			return getUrl(video.VideoUrl);
		}
		public virtual bool hasMultipleVideos(){
			return false;
		}
		public virtual List<GUIOnlineVideos.VideoInfo> getOtherVideoList(GUIOnlineVideos.VideoInfo foVideo){
			return new List<GUIOnlineVideos.VideoInfo>();
		}

		public List<RssItem> getRssDataItems(String fsUrl){
			List<RssItem> loRssItems = new List<RssItem>();
			try{
				XmlDocument doc = new XmlDocument();
				XmlReaderSettings settings = new XmlReaderSettings();
				settings.ProhibitDtd = false;
				//doc.Load(XmlReader.Create(fsUrl,settings));
				
				//WebClient client =new WebClient();
				//String xml = client.DownloadString(fsUrl);
				//doc.LoadXml(xml);
				XmlTextReader reader = new XmlTextReader(fsUrl);
				doc.Load(reader);
				XmlNamespaceManager expr = new XmlNamespaceManager(doc.NameTable);
				expr.AddNamespace("media", "http://search.yahoo.com/mrss");
				expr.AddNamespace("exInfo","http://www.gametrailers.com/rssexplained.php");
				//Create the root XmlNode and generate an XmlNodeList from it.
				XmlNode root = doc.SelectSingleNode("//rss/channel/item", expr);
				XmlNodeList nodeList;
				nodeList = root.SelectNodes("//rss/channel/item");
				//XmlAttributeCollection ac;
				
				RssItem loRssItem;
				//GUIListItem loListItem;
				MediaContent loMediaContent;
				int itemCount = 0;
				foreach (XmlNode chileNode in nodeList)
				{
					if(itemCount>=100){
						break;
					}
					itemCount++;
					loRssItem = new RssItem();

					for (int i = 0; i < chileNode.ChildNodes.Count; i++)
					{
						XmlNode n = chileNode.ChildNodes[i];

						switch (n.Name)
						{
								
							case "title":
								loRssItem.title = n.InnerText;
								break;
							case "link":
								loRssItem.link = n.InnerText;
								break;
							case "guid":
								loRssItem.guid = n.InnerText;
								break;
							case "pubDate":
								loRssItem.pubDate = n.InnerText;
								break;
							case "description":
								loRssItem.description = n.InnerText;
								break;
							case "author":
								loRssItem.author = n.InnerText;
								break;
							case "exInfo:image":
								loRssItem.exInfoImage = n.InnerText;
								break;
                            case "exInfo:gameID":
                                loRssItem.gameID = n.InnerText;
                                break;
							case "feedburner:origLink":
								loRssItem.feedBurnerOrigLink = n.InnerText;
								break;
							case "media:group":
								
								for (int j = 0; j < n.ChildNodes.Count; j++)
								{
									XmlNode nin = n.ChildNodes[j];
									switch (nin.Name)
									{
											
										case "media:content":
											loMediaContent = new MediaContent();
											try{
												loMediaContent.url = nin.Attributes["url"].Value;
												loMediaContent.type = nin.Attributes["type"].Value;
												loMediaContent.medium = nin.Attributes["medium"].Value;
												loMediaContent.duration = nin.Attributes["duration"].Value;
												loMediaContent.height = nin.Attributes["height"].Value;
												loMediaContent.width = nin.Attributes["width"].Value;
											}catch(Exception){};
											loRssItem.contentList.Add(loMediaContent);
											break;
										case "media:description":
											loRssItem.mediaDescription = n.InnerText;
											break;
										case "media:thumbnail":
											loRssItem.mediaThumbnail = nin.Attributes["url"].Value;
											break;
										case "media:title":
											loRssItem.mediaTitle = nin.InnerText;
											break;
											
									}
								}
								break;
							case "media:content":
								loMediaContent = new MediaContent();
								if(n.Attributes["url"]!=null){
									loMediaContent.url = n.Attributes["url"].Value;
								}
								if(n.Attributes["type"]!=null){
									loMediaContent.type = n.Attributes["type"].Value;
								}
								if(n.Attributes["medium"]!=null){
									loMediaContent.medium = n.Attributes["medium"].Value;
								}
								if(n.Attributes["duration"]!=null){
									loMediaContent.duration = n.Attributes["duration"].Value;
								}
								if(n.Attributes["height"]!=null){
									loMediaContent.height = n.Attributes["height"].Value;
								}
								if(n.Attributes["width"]!=null){
									loMediaContent.width = n.Attributes["width"].Value;
								}
								loRssItem.contentList.Add(loMediaContent);
								for (int j = 0; j < n.ChildNodes.Count; j++)
								{
									XmlNode nin = n.ChildNodes[j];
									
									switch (nin.Name)
									{
										case "media:description":
											loRssItem.mediaDescription = n.InnerText;
											break;
										case "media:thumbnail":
											loRssItem.mediaThumbnail = nin.Attributes["url"].Value;
											break;
										case "media:title":
											loRssItem.mediaTitle = nin.InnerText;
											break;
											
									}
								}
								break;
							case "media:description":
								loRssItem.mediaDescription = n.InnerText;
								break;
							case "media:thumbnail":
								loRssItem.mediaThumbnail = n.Attributes["url"].Value;
								break;
							case "media:title":
								loRssItem.mediaTitle = n.InnerText;
								break;
							case "enclosure":
								loRssItem.enclosure = n.Attributes["url"].Value;
								if(n.Attributes["duration"]!=null){
									loRssItem.enclosureDuration = n.Attributes["duration"].Value;
								}
								
								break;
							case "media:category":
								loRssItem.mediaCategory = n.InnerText;
								break;
							default:
								break;
						}
					}
					loRssItems.Add(loRssItem);
				}
			}catch(Exception e){
				Log.Error(e);
			}
			
			return loRssItems;
			
		}
		
		public string getHTMLData(string fsURL)
		{
			BackgroundWorker worker = new BackgroundWorker();
			_workerCompleted = false;
			worker.DoWork += new DoWorkEventHandler(DownloadWorker);
			worker.RunWorkerAsync(fsURL);

			//using (WaitCursor cursor = new WaitCursor())
			//{
			while (_workerCompleted == false){
				//GUIWindowManager.Process();
			}
            String lsHtml = HTMLdownload;
            HTMLdownload = null;
            return lsHtml;
		}
		private string downloadHtml(String fsUrl)
		{
			byte[] HTMLbuffer;
			String lsURL = fsUrl;
			WebClient loWebClient = new WebClient();
			loWebClient.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
			HTMLbuffer = loWebClient.DownloadData(lsURL);

			String HTMLdownload = Encoding.UTF8.GetString(HTMLbuffer);
			//HTMLdownload = convertHtmlToText(HTMLdownload);
			return HTMLdownload;

		}
		public void DownloadWorker(object sender, DoWorkEventArgs e)
		{

			HTMLdownload = downloadHtml((String)e.Argument);
			_workerCompleted = true;
			//return HTMLdownload;
		}
		public abstract String getSiteId();
		
		protected bool isPossibleVideo(string fsUrl){
			string extensionFile = System.IO.Path.GetExtension(fsUrl).ToLower();
			if(String.IsNullOrEmpty(extensionFile))return true;
			foreach (string extension in m_VideoExtensions)
			{
				if (extension == extensionFile) return true;
			}
			return false;
			
		}
		protected List<String>parseASX(String fsAsxUrl){
			String lsAsxData = getHTMLData(fsAsxUrl);
			MatchCollection videoUrls = Regex.Matches(lsAsxData,"<Ref\\shref=\"(?<url>[^\"]*)");
			List<String> urlList = new List<String>();
			foreach(Match videoUrl in videoUrls){
				urlList.Add(videoUrl.Groups["url"].Value);
			}
			return urlList;
			
		}
		public virtual bool MultipleFilePlay(){
			return false;
		}
		public virtual List<String> getMultipleVideoUrls(GUIOnlineVideos.VideoInfo video,GUIOnlineVideos.SiteSettings foSite){
			return new List<String>();
		}
        public virtual bool hasLoginSupport()
        {
            return false;
        }
        public virtual bool hasConfirmAge()
        {
            return false;
        }
        
		

	}
}
